home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
pascal
/
gsdbloo.exe
/
GS_EDIT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-02-24
|
23KB
|
772 lines
Unit GS_Edit;
{-----------------------------------------------------------------------------
Editor Routines
GS_Edit Copyright (c) Richard F. Griffin
10 January 1991
102 Molded Stone Pl
Warner Robins, GA 31088
-------------------------------------------------------------
This unit handles the objects for a simple editor similar to
WordStar.
Changes:
18 May 91 - Modified Presssed_Del to bring up the succeeding line
if the cursor is at the end of the line.
06 Jun 91 - Modified startup routine to initialize the windows. all
instances will use the same window object.
20 Feb 92 - Added a Done destructor to allow dynamic allocation and
deallocation of the object.
------------------------------------------------------------------------------}
interface
{$D-}
uses
CRT,
Dos,
GS_KeyI,
GS_Scrn,
GS_Winfc,
GS_Error,
GS_Strng;
type
GS_Edit_Pntr = ^GS_Edit_Line;
GS_Edit_Line = record
Next_Line,
Prev_Line : GS_Edit_Pntr;
Return_Cod : byte;
Line_Size : integer;
Valu_Line : string;
end;
GS_Edit_Blok = record
Blok_Line,
Blok_Colm : integer;
end;
GS_Edit_Objt = object
First_Line,
End_Line,
Work_Line : GS_Edit_Pntr;
{Used to track lines}
Cursor_LocX,
Cursor_LocY : word;
{Hold cursor location}
Active_Line, {Current line number}
Total_Lines, {Total number of lines}
Screen_Top, {Line number at top of screen}
Screen_Btm : longint;
{Line Number at bottom of screen}
CursorPos : integer;
{Position in line}
CursorLine : integer;
{Line currently working on}
Temp_Line : string;
{work area during wordwrap}
Edit_Lgth : integer;
{Max size of eaach line}
Lines_Avail : integer;
{Number of lines that will fit in the}
{window on the screen}
Ch_Work : char;
{Hold area for keystrokes}
Word_Wrap : boolean;
{True sets word wrap on}
WW_Flag : boolean;
{Internal flag for wordwrap condition}
Blok_Begin,
Blok_Fini : GS_Edit_Blok;
{Future use for block operations}
constructor Init;
destructor Done;
function Byte_Count : longint;
procedure Check_Func_Keys;
procedure Clear_Editor;
procedure Edit;
Procedure Edit_Line;
function Find_Line(linenum : integer) : boolean;
function Get_Line_Mem(lth : integer) : pointer;
Procedure Rel_Line_Mem(linenum : integer);
Procedure Show_Lines(b, e :integer);
Procedure View;
Procedure WordWrap(Fline : string);
Procedure Pressed_Bsp;
Procedure Pressed_CrtlY;
Procedure Pressed_Del;
Procedure Pressed_DnAr;
Procedure Pressed_F1;
Procedure Pressed_Ret;
Procedure Pressed_UpAr;
Procedure Pressed_PgUp;
Procedure Pressed_PgDn;
end;
implementation
var
StatWin,
HelpWin,
EditWin : GS_Wind_Objt;
constructor GS_Edit_Objt.Init;
begin
First_Line := nil;
End_Line := nil;
Work_Line := nil;
Word_Wrap := true;
WW_Flag := false;
Active_Line := 0;
Total_Lines := 0;
Screen_Top := 0;
Screen_Btm := 0;
Ch_Work := #0;
CursorPos := 1;
CursorLine := 1;
Temp_Line := '';
GS_KeyI_Ins := True; {Start in insert mode}
Edit_Lgth := 32;
end;
destructor GS_Edit_Objt.Done;
begin
Clear_Editor;
end;
function GS_Edit_Objt.Byte_Count : longint;
var
i : longint;
p : GS_Edit_Pntr;
begin
i := 0;
p := First_Line;
while (p <> nil) do
begin
i := i + length(p^.Valu_Line) + 2;
{Add length of line + CR/LF chars}
p := p^.Next_Line;
end;
inc(i); {Add one for EOF byte}
Byte_Count := i;
end;
procedure GS_Edit_Objt.Clear_Editor;
begin
Work_Line := First_Line;
while (Work_Line <> nil) do
begin
End_Line := Work_Line^.Next_Line;
FreeMem(Work_Line,Work_Line^.Line_Size);
Work_Line := End_Line;
end;
First_Line := nil;
End_Line := nil;
Work_Line := nil;
Active_line := 0;
Total_Lines := 0;
end;
procedure GS_Edit_Objt.Pressed_F1;
var
cc : char;
begin
HelpWin.SetWin;
writeln('Toggle Ins - Ins');
writeln('Delete Char - Del');
writeln('Delete Line - Ctl-Y');
writeln('Press any Key');
cc := ReadKey;
if cc = #0 then cc := ReadKey;
HelpWin.RelWin;
end;
procedure GS_Edit_Objt.Pressed_Bsp;
var
bb : byte;
ss : string;
ll : boolean;
begin
if CursorPos > 1 then
begin
Delete(Work_Line^.Valu_Line, Pred(CursorPos), 1);
GoToXY(1, CursorLine);
Write(Work_Line^.Valu_Line);
ClrEol;
Dec(CursorPos);
end
else
begin
if Active_Line > 1 then
begin
bb := Work_line^.Return_Cod;
ss := Work_Line^.Valu_Line;
if Active_Line < Total_Lines then
begin
Pressed_CrtlY;
Pressed_UpAr;
end else Pressed_CrtlY;
Work_Line^.Return_Cod := bb;
ss := Work_Line^.Valu_Line + ss;
CursorPos := length(Work_Line^.Valu_Line);
WordWrap(ss);
GotoXY(1,succ(Active_Line-Screen_Top));
write(Work_Line^.Valu_Line);
end;
end;
end;
procedure GS_Edit_Objt.Pressed_Del;
begin
if CursorPos <= Length(Work_Line^.Valu_Line) then
begin
Delete(Work_Line^.Valu_Line, CursorPos, 1);
GoToXY(1, CursorLine);
Write(Work_Line^.Valu_Line);
ClrEol;
end
else
begin
if Active_Line < Total_Lines then
begin
Pressed_DnAr;
CursorPos := 1;
Pressed_Bsp;
end;
end;
end;
procedure GS_Edit_Objt.Pressed_PgDn;
begin {Page Down}
Active_Line := pred(Screen_Top + Lines_Avail);
if Active_Line > Total_Lines then Active_Line := Total_Lines;
if not Find_Line(Active_Line) then
begin
ShowError(710,'Pressed_PgDn');
exit;
end;
if Active_Line <> Screen_Top then Show_Lines(Active_Line,Total_Lines);
CursorLine := 1;
if length(Work_Line^.Valu_Line)+1 < CursorPos then
CursorPos := length(Work_Line^.Valu_Line)+1;
end;
procedure GS_Edit_Objt.Pressed_PgUp;
begin {Page Up}
if Active_Line <= 1 then exit;
Active_Line := succ(Screen_Top - Lines_Avail);
if Active_Line < 1 then Active_Line := 1;
if not Find_Line(Active_Line) then
begin
ShowError(710,'Pressed_PgUp');
exit;
end;
if Active_Line < Screen_Top then Show_Lines(Act